package com.zdkj.subway.check.controller.subwayRat.conductorDifferences.shoupiaoyuan;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zdkj.admin.api.entity.SysUser;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.check.controller.CommonController;
import com.zdkj.subway.check.entity.*;
import com.zdkj.subway.check.enums.ResultDetailMsg;
import com.zdkj.subway.check.mapper.SwAuCenterConductorAmountDifferenceMapper;
import com.zdkj.subway.check.mapper.SwAuConductorNoticeMapper;
import com.zdkj.subway.check.mapper.SwAuConductorShortMapper;
import com.zdkj.subway.check.result.Result;
import com.zdkj.subway.check.util.CheckAccount;
import com.zdkj.subway.check.util.DateFormat;
import com.zdkj.subway.check.util.JdbcUtil;
import com.zdkj.subway.check.util.UserInfo;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 2-2-17、售票员票款差异通知SW_AU_CONDUCTOR_NOTICE
 */
@Slf4j
@RestController
@RequestMapping("/check")
public class SwAuConductorNoticeController {
    @Resource
    SwAuConductorNoticeMapper swAuConductorNoticeMapper;
    @Resource
    SwAuConductorShortMapper swAuConductorShortMapper;
    @Autowired
    private CommonController commonController;
    @Resource
    SwAuCenterConductorAmountDifferenceMapper swAuCenterConductorAmountDifferenceMapper;

    /**
     * 售票员票款差异通知列表
     * @param page
     * @param param
     * @return
     */
    @RequestMapping("/getSwAuConductorNoticeList")
    @ApiOperation(value = "售票员票款差异通知列表", notes = "售票员票款差异通知列表")
    public Page getSwAuConductorNoticeList(Page page, @RequestParam Map<String,String> param){
        List<Map<String,Object>> res=swAuConductorNoticeMapper.getSwAuConductorNoticeList(param);
        page.setData(res,true);
        return page;
    }

    /**
     * 设置回复期限
     * @param swAuConductorNotice
     * @return
     */
    @RequestMapping("/setReplyPeriod")
    @ApiOperation(value = "设置回复期限", notes = "设置回复期限")
    public Result setReplyPeriod( String ids, SwAuConductorNotice swAuConductorNotice){
        Result res=new Result(ResultDetailMsg.OK);
        try {
            UpdateWrapper<SwAuConductorNotice> updateWrapper=new UpdateWrapper<>();
            updateWrapper.in("id",ids.split(","));
            swAuConductorNoticeMapper.update(swAuConductorNotice,updateWrapper);
        }catch (Exception e){
            log.error("{}",e);
            res.setMsg("设置回复期限天数失败");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
        }
        return res;
    }

    /**
     * 申诉回复 走审批
     * @param swAuConductorNotice
     * @return
     */
    @RequestMapping("/setAppealReply")
    @ApiOperation(value = "申诉回复 走审批", notes = "申诉回复 走审批")
    public Result setAppealReply( String ids, SwAuConductorNotice swAuConductorNotice){
        Result res=new Result(ResultDetailMsg.OK);
        try {
            if(swAuConductorNotice.getApproverName()==null){
                PigxUser user = SecurityUtils.getUser();
                swAuConductorNotice.setApproverName(user.getNikeName());//审批人
                swAuConductorNotice.setApproverJob(user.getUserCode());//审批人工号
                swAuConductorNotice.setApproverTime(new Date());//审批时间
            }
            if("2".equals(swAuConductorNotice.getAuditSate())&&!"6".equals(swAuConductorNotice.getAppealStatus())){
                swAuConductorNotice.setAppealStatus("3");//申诉成功
            }else if("3".equals(swAuConductorNotice.getAuditSate())&&!"6".equals(swAuConductorNotice.getAppealStatus())){
                swAuConductorNotice.setAppealStatus("4");//申诉失败
            }
            UpdateWrapper<SwAuConductorNotice> updateWrapper=new UpdateWrapper<>();
            updateWrapper.in("id",ids.split(","));
            swAuConductorNoticeMapper.update(swAuConductorNotice,updateWrapper);
            //TODO 如果是超期申诉审批通过，也同时查找是否存在补款信息数据，存在进行删除
            if("2".equals(swAuConductorNotice.getAuditSate())){
                LambdaQueryWrapper<SwAuConductorShort> wrapper =
                        Wrappers.<SwAuConductorShort>lambdaQuery().in(SwAuConductorShort::getNoticeId, Arrays.asList(ids.split(",")));
                swAuConductorShortMapper.delete(wrapper);
            }
            if("3".equals(swAuConductorNotice.getAuditSate())){//审批不通过

                List<SwAuConductorNotice> swAuConductorNotices = swAuConductorNoticeMapper.selectBatchIds(Arrays.asList(ids.split(",")));
                /*
                String sw_pm_time_sql = "select * from sw_pm_time";
                List<Map<String, Object>> sw_pm_time_resp = JdbcUtil.exeSqlQuery(sw_pm_time_sql);
                Object conductorReplenishValidity = sw_pm_time_resp.get(0).get("CONDUCTOR_REPLENISH_validity");//补款期限
				*/
                for(SwAuConductorNotice s:swAuConductorNotices){
                    SwAuConductorShort swAuConductorShort=new SwAuConductorShort();
                    swAuConductorShort.setNoticeId(s.getId());
                    swAuConductorShort.setDiffId(s.getRelationid());
                    swAuConductorShort.setLineCode(s.getLineCode());
                    swAuConductorShort.setStationCode(s.getStationCode());
                    swAuConductorShort.setCheckTime(s.getRecordTime());
                    swAuConductorShort.setConductorPersonCode(s.getConductorPersonCode());
                    //TODO 审批不通过 根据线路、车站、售票员、收益日期四个条件判断如果之前存在补款信息，将数据进行更新
                    QueryWrapper<SwAuConductorShort> query = Wrappers.query(swAuConductorShort);
                    SwAuConductorShort serviceOne = swAuConductorShortMapper.selectOne(query);
                    if(ObjectUtil.isNotEmpty(serviceOne)){
                        swAuConductorShort.setId(serviceOne.getId());
                    }
                    String dateExStr = DateFormat.date_ex_str(s.getRecordTime());
                    String sql="select date_add(a.END_TIME,interval 1 second) startSettleDate,date_add(a.END_TIME,interval (ifnull(b.TVM_SETTLEMENT_TERM,1))-1 day) endSettleDate\n" +
                            " from SW_CK_DATA_SUBMIT a\n" +
                            " left join sw_pm_long_period_settlement b on  a.LINE_CODE = b.LINE_CODE  and a.STATION_CODE = b.STATION_CODE and b.DEL_FLAG = '0' and b.STATUS='1'\n" +
                            " where  a.LINE_CODE = '"+s.getLineCode()+"'\n" +
                            " and a.STATION_CODE = '"+s.getStationCode()+"'\n"+
						    " and '"+dateExStr+"' BETWEEN  DATE_FORMAT(date_add(a.END_TIME,interval 1 second),'%Y-%m-%d') and DATE_FORMAT(date_add(a.END_TIME,interval (ifnull(b.TVM_SETTLEMENT_TERM,1))-1 day),'%Y-%m-%d')";
                    List<Map<String, Object>> r = JdbcUtil.exeSqlQuery(sql);
					Date startTime=new Date();
					Date endTime=new Date();
					if(r!=null && r.size()>0){//不是历史的收益日期					  
                      startTime=(Date) (r.size()>0?r.get(0).get("startSettleDate"):startTime);
                      endTime=(Date) (r.size()>0?r.get(0).get("endSettleDate"):endTime);
                     
					}else{
					   sql = "select a.BEGIN_TIME startSettleDate," +
                             " date_add(a.END_TIME,interval -1 day) endSettleDate" +
                             " from sw_ck_data_submit_log a " +
                             " where  a.LINE_CODE =  '"+s.getLineCode()+"'" +
                             " and a.STATION_CODE = '"+s.getStationCode()+"'"+
                             " and  '"+dateExStr+"' BETWEEN  DATE_FORMAT(a.BEGIN_TIME ,'%Y-%m-%d') and DATE_FORMAT(date_add(a.END_TIME,interval -1 day),'%Y-%m-%d') ";
					    List<Map<String, Object>> rLog = JdbcUtil.exeSqlQuery(sql);
						 if(rLog!=null && rLog.size()>0){//不是历史的收益日期					  
								  startTime=(Date) (rLog.size()>0?rLog.get(0).get("startSettleDate"):startTime);
								  endTime=(Date) (rLog.size()>0?rLog.get(0).get("endSettleDate"):endTime);								 
                          }
					}
					swAuConductorShort.setIncomeSettleBeginTime(startTime);
                    swAuConductorShort.setIncomeSettleEndTime(endTime);
                    
                    swAuConductorShort.setShortAmount(s.getDifferenceAmount().abs());
                    swAuConductorShort.setConductorPersonId(0);
                    swAuConductorShort.setConductorPerson(s.getConductorPersonName());
                    swAuConductorShort.setEquipmentNumber(s.getEquipmentNumber());
                    swAuConductorShort.setBomCode(s.getBomCode());
                    swAuConductorShort.setIsNotice(0);
                    swAuConductorShort.setIsSupPayment(0);
                    swAuConductorShort.setCreatorId(UserInfo.getId());
                    swAuConductorShort.setCreatorName(UserInfo.getName());
                    swAuConductorShort.setCreateTime(new Date());
                    swAuConductorShort.setUpdateTime(new Date());
                    swAuConductorShort.setSupPaymentTimelimit(new Date());
                    swAuConductorShort.setSupPaymentLimit(CheckAccount.getLimitTime("CONDUCTOR_REPLENISH_validity"));//补款期限 Integer.valueOf(conductorReplenishValidity.toString()));
                    int i = s.getDifferenceAmount().compareTo(new BigDecimal("0"));
                    //差异金额小于0时才加入到补款通知
                    if(i == -1){
                        if(swAuConductorShort.getId() != null){
                            swAuConductorShortMapper.updateById(swAuConductorShort);
                        }else {
                            swAuConductorShortMapper.insert(swAuConductorShort);
                        }
                    }
                }
            }
        }catch (Exception e){
            log.error("{}",e);
            res.setMsg("申诉回复失败");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
        }
        return res;
    }

    /**
     * 下发
     * @param param
     * @return
     */
    @RequestMapping("/sendStatusUpdate")
    @ApiOperation(value = "下发", notes = "下发")
    @Transactional(rollbackFor = Exception.class)
    public Result sendStatusUpdate(@RequestBody Map<String,Object> param){
        String ids = String.valueOf(param.get("ids"));
        Result res=new Result(ResultDetailMsg.OK);
        try {
            UpdateWrapper<SwAuConductorNotice> updateWrapper=new UpdateWrapper<>();
            updateWrapper.in("id",ids.split(","));
            SwAuConductorNotice swAuConductorNotice = new SwAuConductorNotice();
            swAuConductorNotice.setSendStatus(String.valueOf(param.get("sendStatus")));
            swAuConductorNotice.setSendTime(new Date()); //下发时间
            swAuConductorNotice.setAppealStatus("1"); //下发时默认待申诉
            swAuConductorNoticeMapper.update(swAuConductorNotice,updateWrapper);
            //根据不同类型发代办
            commonController.innerBatch(param);
        }catch (Exception e){
            log.error("{}",e);
            res.setMsg("下发失败");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return res;
    }

    /**
     * TODO 单个审批 弃用
     * @param swAuConductorNotice
     * @return
     */
    @RequestMapping("/approveData")
    @ApiOperation(value = "单个审批 弃用", notes = "单个审批 弃用")
    public Result approveData( String ids, SwAuConductorNotice swAuConductorNotice){
        Result res=new Result(ResultDetailMsg.OK);
        try {
            UpdateWrapper<SwAuConductorNotice> updateWrapper=new UpdateWrapper<>();
            updateWrapper.in("id",ids.split(","));
            swAuConductorNoticeMapper.update(swAuConductorNotice,updateWrapper);

            if("3".equals(swAuConductorNotice.getAuditSate())){//审批不通过

                List<SwAuConductorNotice> swAuConductorNotices = swAuConductorNoticeMapper.selectBatchIds(Arrays.asList(ids.split(",")));
                for(SwAuConductorNotice s:swAuConductorNotices){
                    SwAuConductorShort swAuConductorShort=new SwAuConductorShort();
                    swAuConductorShort.setNoticeId(s.getId());
                    swAuConductorShort.setDiffId(s.getRelationid());
                    swAuConductorShort.setLineCode(s.getLineCode());
                    swAuConductorShort.setStationCode(s.getStationCode());
                    swAuConductorShort.setCheckTime(s.getRecordTime());

                    String sql="select date_add(a.END_TIME,interval 1 second) startSettleDate,date_add(a.END_TIME,interval (ifnull(b.TVM_SETTLEMENT_TERM,1)) day) endSettleDate\n" +
                            " from SW_CK_DATA_SUBMIT a\n" +
                            " left join sw_pm_long_period_settlement b on  a.LINE_CODE = b.LINE_CODE  and a.STATION_CODE = b.STATION_CODE and b.DEL_FLAG = '0' and b.STATUS='1'\n" +
                            " where  a.LINE_CODE = '"+s.getLineCode()+"'\n" +
                            " and a.STATION_CODE = '"+s.getStationCode()+"'";
                    List<Map<String, Object>> r = JdbcUtil.exeSqlQuery(sql);
                    Date startTime=new Date();Date endTime=new Date();
                    startTime=(Date) (r.size()>0?r.get(0).get("startSettleDate"):startTime);
                    endTime=(Date) (r.size()>0?r.get(0).get("endSettleDate"):endTime);

                    swAuConductorShort.setIncomeSettleBeginTime(startTime);
                    swAuConductorShort.setIncomeSettleEndTime(endTime);
                    swAuConductorShort.setShortAmount(s.getDifferenceAmount().abs());
                    swAuConductorShort.setConductorPersonId(0);
                    swAuConductorShort.setConductorPersonCode(s.getConductorPersonCode());
                    swAuConductorShort.setConductorPerson(s.getConductorPersonName());
                    swAuConductorShort.setEquipmentNumber(s.getEquipmentNumber());
                    swAuConductorShort.setBomCode(s.getBomCode());
                    swAuConductorShort.setIsNotice(0);
                    swAuConductorShort.setIsSupPayment(0);
                    swAuConductorShort.setCreatorId(UserInfo.getId());
                    swAuConductorShort.setCreatorName(UserInfo.getName());
                    swAuConductorShort.setCreateTime(new Date());
                    swAuConductorShort.setUpdateTime(new Date());
                    swAuConductorShortMapper.insert(swAuConductorShort);
                }
            }
        }catch (Exception e){
            log.error("{}",e);
            res.setMsg("下发失败");
            res.setResult(ResultDetailMsg.CHECK_UPDATE_ERROR);
        }
        return res;
    }


    /**
     * 人工添加售票员差异确认通知
     * @param swAuConductorNotice
     * @return
     */
    @ApiOperation(value = "人工添加售票员差异确认通知", notes = "人工添加售票员差异确认通知")
    @SysLog("人工添加售票员差异确认通知" )
    @PostMapping("/manuallyAdd")
    public R save(@RequestBody SwAuConductorNotice swAuConductorNotice) {
        //SysUser user = swAuConductorNoticeMapper.getEqNum(swAuConductorNotice.getConductorPersonCode());
        //if(StringUtils.isEmpty(user.getDeviceOperateNo())){  人工添加前台页面设置设备操作号
		if(StringUtils.isEmpty(swAuConductorNotice.getEquipmentNumber())){
            return R.failed("此员工未找到设备操作号！");
        }
		
        swAuConductorNotice.setDifferenceAmount(swAuConductorNotice.getDifferenceAmount().multiply(new BigDecimal("100")));
        swAuConductorNotice.setRelationid(0);//人工添加关联id为0
        //swAuConductorNotice.setEquipmentNumber(user.getDeviceOperateNo());
		swAuConductorNotice.setEquipmentNumber(swAuConductorNotice.getEquipmentNumber());
        swAuConductorNotice.setDataSource("1");//人工添加
        swAuConductorNotice.setReplyPeriod(CheckAccount.getConductorNoticeLimit()); //TODO 回复期限天数之后是不是改为配置的
        swAuConductorNotice.setIsSupPayment(0);
        //通知状态
        swAuConductorNotice.setNoticeState("1");
        //申诉状态
        swAuConductorNotice.setAppealStatus("1");
        //申诉类型 期限内1 期限外超期申诉2
        swAuConductorNotice.setAppealType("1");
        //审核状态
        swAuConductorNotice.setAuditSate("1");
        //下发状态
        swAuConductorNotice.setSendStatus("1");
        swAuConductorNotice.setIsSupPayment(1);//是否补款  0；未加入补款 1；未补款 3；已补款
        swAuConductorNotice.setSaleoperatorConfirmStatus("0");
        swAuConductorNotice.setCreatorName(UserInfo.getUserName());
        swAuConductorNotice.setCreatorId(UserInfo.getId());
        swAuConductorNotice.setCreateTime(new Date());
        return R.ok(swAuConductorNoticeMapper.insert(swAuConductorNotice));
    }

    /**
     * 通过id查询售票员差异确认通知
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询", hidden = true)
    @GetMapping("/getById/{id}" )
    public R getById(@PathVariable("id") Integer id) {
        return R.ok(swAuConductorNoticeMapper.selectById(id));
    }

    /**
     * 人工修改售票员差异确认通知
     * @param swAuConductorNotice
     * @return
     */
    @ApiOperation(value = "人工修改售票员差异确认通知", notes = "人工修改售票员差异确认通知")
    @SysLog("人工修改售票员差异确认通知" )
    @PutMapping("/manuallyAudit")
    public R updateById(@RequestBody SwAuConductorNotice swAuConductorNotice) {
        swAuConductorNotice.setDifferenceAmount(swAuConductorNotice.getDifferenceAmount().multiply(new BigDecimal("100")));
        return R.ok(swAuConductorNoticeMapper.updateById(swAuConductorNotice));
    }

    /**
     * 通过id列表删除售票员差异确认通知
     * 待下发以及已下发的都可以删除，同时如果有补款数据，同时将补款数据删除。
     * @param ids ids
     * @return R
     */
    @ApiOperation(value = "通过id列表删除售票员差异确认通知", notes = "通过id列表删除售票员差异确认通知")
    @SysLog("通过id列表删除售票员差异确认通知" )
    @PreAuthorize("@pms.hasPermission('sw_au_conductor_notice_del')")
    @GetMapping("/removeByIds" )
    public R removeByIds(@RequestParam(value = "ids") List<Integer> ids) {
        List<SwAuConductorNotice> swAuConductorNotices = swAuConductorNoticeMapper.selectBatchIds(ids);
        List<Integer> integerList =
                swAuConductorNotices.stream().map(SwAuConductorNotice::getRelationid).collect(Collectors.toList());
        //删除售票员差异确认通知
        swAuConductorNoticeMapper.deleteBatchIds(ids);
        //修改售票员审核主表通知状态改为未通知
        LambdaUpdateWrapper<SwAuCenterConductorAmountDifference> updateWrapper =
                Wrappers.<SwAuCenterConductorAmountDifference>lambdaUpdate()
                        .set(SwAuCenterConductorAmountDifference::getNoticeSate, "1")
			            .set(SwAuCenterConductorAmountDifference::getSuppState,"0")
			            .in(SwAuCenterConductorAmountDifference::getId, integerList);
        swAuCenterConductorAmountDifferenceMapper.update(null,updateWrapper);
        //如果有补款数据，同时将补款数据删除。
        LambdaQueryWrapper<SwAuConductorShort> wrapper =
                Wrappers.<SwAuConductorShort>lambdaQuery().in(SwAuConductorShort::getNoticeId, ids);
        return R.ok(swAuConductorShortMapper.delete(wrapper));
    }
}
